package org.yzh.web.service.impl;

import com.github.dozermapper.core.Mapper;
import com.ling5821.mtime.Mtime;
import com.qiniu.processing.OperationStatus;
import com.qiniu.storage.model.FileInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yzh.web.commons.RandomUtils;
import org.yzh.web.component.qiniu.QiniuManager;
import org.yzh.web.mapper.VideoDownloadMapper;
import org.yzh.web.model.APIException;
import org.yzh.web.model.entity.DeviceDO;
import org.yzh.web.model.entity.VideoDownloadDO;
import org.yzh.web.model.enums.DefaultCodes;
import org.yzh.web.model.vo.*;
import org.yzh.web.service.DeviceService;
import org.yzh.web.service.VideoDownloadService;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author lsj
 * @date 2021/1/17 15:36
 */
@Service
public class VideoDownloadServiceImpl implements VideoDownloadService {

    @Autowired
    private VideoDownloadMapper videoDownloadMapper;

    @Autowired
    private DeviceService deviceService;

    @Autowired
    private Mapper dozerMapper;

    @Autowired
    private QiniuManager qiniuManager;

    @Override
    public int delete(Long id) {
        return videoDownloadMapper.delete(id);
    }

    @Override
    public int insert(VideoDownloadDO record) {
        return videoDownloadMapper.insert(record);
    }

    @Override
    public int batchInsert(List<VideoDownloadDO> records) {
        return videoDownloadMapper.batchInsert(records);
    }

    @Override
    public List<VideoDownloadDO> find(VideoDownloadQuery query) {
        return videoDownloadMapper.find(query);
    }

    @Override
    public List<VideoDownload> findHistory(VideoDownloadQuery query) {
        return find(query).stream().map(item -> dozerMapper.map(item, VideoDownload.class)).collect(Collectors.toList());
    }

    @Override
    public int update(VideoDownloadDO record) {
        return videoDownloadMapper.update(record);
    }

    @Override
    public int addVideoDownload(VideoDownloadForm form) {
        DeviceQuery deviceQuery = new DeviceQuery();
        deviceQuery.setPlateNo(form.getPlateNo());
        deviceQuery.setDeviceId(form.getDeviceId());
        Optional<DeviceDO> unique = deviceService.findUnique(form.getDeviceId(), form.getPlateNo());

        if (!unique.isPresent()) {
            throw new APIException(DefaultCodes.UnregisteredRes);
        }

        DeviceDO device = unique.get();
        VideoDownloadDO record = new VideoDownloadDO();
        record.setStartDateTime(form.getStartDateTime());
        record.setEndDateTime(form.getEndDateTime());
        record.setDeviceId(device.getDeviceId());
        record.setMobileNo(device.getMobileNo());
        record.setPlateNo(device.getPlateNo());
        /* 初始大小为零 */
        record.setSize(0L);
        record.setCreateTime(LocalDateTime.now());
        RecordClipsSaveResult result = qiniuManager.recordClipsSaveAsMp4(device.getDeviceId(),
            this.generateVideoFileName(device.getPlateNo(), form.getStartDateTime(), form.getEndDateTime()),
            (int)Mtime.toEpochSecond(form.getStartDateTime()), (int)Mtime.toEpochSecond(form.getEndDateTime()));

        if (result.getCode() == 200) {
            record.setUrl(result.getFileUrl());
            record.setStatus(VideoDownloadDO.PROCESSING);
            record.setPersistentId(result.getPersistentId());
            record.setBucket(result.getBucket());
            record.setFileName(result.getFname());
            return insert(record);
        } else if (result.getCode() == 612){
            throw new APIException(DefaultCodes.VideoNotFound);
        } else {
            throw new APIException(DefaultCodes.UnknownError);
        }
    }

    private String generateVideoFileName(String keyword, LocalDateTime startDateTime, LocalDateTime endDateTime) {
        return "mobileye/record/" + keyword + "-" + Mtime.format(startDateTime) + "-" + Mtime.format(endDateTime) + "-"
            + RandomUtils.nextNumber(8);
    }

    @Override
    public void updateVideoDownloadStatus() {
        VideoDownloadQuery query = new VideoDownloadQuery();
        query.setStatus(VideoDownloadDO.PROCESSING);
        List<VideoDownloadDO> videoDownloads = this.find(query);
        for (VideoDownloadDO videoDownloadDO : videoDownloads) {
            OperationStatus operationStatus = qiniuManager.getOperationStatus(videoDownloadDO.getPersistentId());
            if (operationStatus.code == 0) {
                FileInfo fileInfo = qiniuManager.getFileInfo(videoDownloadDO.getBucket(), videoDownloadDO.getFileName());
                if(fileInfo != null) {
                    videoDownloadDO.setSize(fileInfo.fsize);
                    videoDownloadDO.setStatus(VideoDownloadDO.SUCCESS);
                }
            }
            this.update(videoDownloadDO);
        }
    }
}
